<template>
  <div class="verification-record-list">
    <div class="overflow-visible">
      <el-card class="mb10">
        <div class="search-dropdown-container">
       漏洞分析
          <div
            class="search-input-wrapper"
            :class="{ 'is-focus': isSearchFocused }"
          >
            <el-input
              ref="searchInputRef"
              v-model="rec.title"
              placeholder="搜索漏洞名称"
              clearable
              style="width: 100%"
              @focus="handleSearchFocus"
              @blur="handleSearchBlur"
              @clear="handleSearchClear"
              @input="handleSearchInput"
            >
              <template #suffix>
                <el-icon class="search-icon" :class="{ rotate: isSearching }">
                  <Search v-if="!isSearching" />
                  <Loading v-else />
                </el-icon>
              </template>
            </el-input>

            <!-- 下拉搜索结果 -->
            <div
              v-show="showDropdown && (rec.list.length > 0 || isSearching)"
              class="search-dropdown"
            >
              <div class="dropdown-content" @scroll="handleDropdownScroll">
                <div
                  v-for="item in rec.list"
                  :key="item.id"
                  class="dropdown-item"
                  :class="{ 'is-selected': rec.checkedId === item.id }"
                  @mousedown.prevent="selectVulnerability(item)"
                >
                  <div class="item-content">
                    <div class="item-title">
                      <span class="text"
                        v-html="highlightMatch(item.title, rec.title)"
                      ></span>
                      <el-tag :type="getTagType(item.level)" size="small">{{
                        formatLevel(item.level)
                      }}</el-tag>
                    </div>
                    <div class="item-meta">
                      <span class="item-id">ID: {{ item.id }}</span>
                      <span class="item-type">{{ item.vuln_type }}</span>
                    </div>
                  </div>
                </div>

                <!-- 加载更多指示器 -->
                <div v-if="isLoadingMore" class="loading-more-item">
                  <el-icon class="is-loading"><Loading /></el-icon>
                  <span>加载更多...</span>
                </div>

                <!-- 无更多数据提示 -->
                <div
                  v-if="!hasMore && rec.list.length > 0"
                  class="no-more-item"
                >
                  没有更多数据了
                </div>

                <!-- 无搜索结果 -->
                <div
                  v-if="rec.list.length === 0 && !isSearching && rec.title"
                  class="no-result-item"
                >
                  <el-icon><Search /></el-icon>
                  <span>未找到匹配的漏洞</span>
                </div>
              </div>
            </div>
          </div>

        </div>
      </el-card>
    </div>
    <div class="top">
      <!-- 搜索表单 -->
      <search-form
        v-model="searchForm"
        :loading="loading"
        :inline="true"
        @search="handleSearch"
        @reset="handleReset"
      >
        <el-form-item label="漏洞名称">
          <el-input v-model="vuln_title" placeholder="请输入漏洞名称" />
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            @change="handleDateRangeChange"
          />
        </el-form-item>
      </search-form>
    </div>
    <!-- 漏洞列表 -->
    <base-table
      :data="tableData"
      :loading="loading"
      :total="total"
      v-model:page="page"
      v-model:limit="limit"
      @pagination="handlePagination"
      @selection-change="handleSelectionChange"
    >
      <el-table-column prop="title" label="漏洞名称">
        <template #default="{ row }">
          <el-tooltip :content="row.title" placement="top" :show-after="1000">
            <span class="ellipsis">{{ row.title }}</span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="status_info" label="状态" width="140">
        <template #default="{ row }">
          <div class="status-badge" :class="getStatusClass(row.status)">
            <span class="status-indicator"></span>
            {{ row.status_info }}
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="create_time" label="漏洞时间" width="170">
        <template #default="{ row }">
          {{ dayjs(row.create_time).format("YYYY-MM-DD HH:mm:ss") }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="300">
        <template #default="{ row }">
          <el-button type="primary" link icon="View" @click="handleViewDetails(row)"
            >查看详情</el-button
          >
          <el-button type="primary" link icon="Discount" @click="handleDetail(row)"
            >分析结果</el-button
          >
          <el-button type="danger" link icon="Delete" @click="handleDelete(row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </base-table>
    <AnalysisModal
      v-model="visible"
      title="分析结果"
      :detailInfo="detailInfo"
      @closed="handleDetailClosed"
    />
    <!-- 漏洞详情弹窗 -->
    <VulnDetailDialog
      v-model="detailVisible"
      :vuln-data="currentVulnData"
      @closed="handleDetailClosed"
    />
  </div>
</template>

<script setup>
import SearchForm from "@/components/SearchForm/index.vue";
import BaseTable from "@/components/BaseTable/index.vue";
import { ref, reactive, onMounted, onUnmounted } from "vue";
import VulnDetailDialog from "@/components/vulnDetailDialog/index.vue";
import { getVulnTaskList } from "@/api/topo";
import {
  getVulnerabilityList,
  getVulnAnalysis,
  createVulnTask,
  getTaskList,
  deleteVulnTask,
} from "@/api/vulnerability";
import debounce from "lodash/debounce";
import AnalysisModal from "./components/AnalysisModal.vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import dayjs from "dayjs";
import { getVulnDetailById } from "@/api/vulnVerification";
import { useCommonStore } from "../../stores/common";
const loading = ref(false);
const visible = ref(false);
const tableData = ref([]);
const page = ref(1);
const limit = ref(10);
const total = ref(0);
const dateRange = ref([]);
const name = ref("");
const vuln_title = ref("");
const router = useRouter();
const searchForm = reactive({});
const selectedRows = ref([]);
const timerId = ref(null);
const detailInfo = ref(null);

// 搜索下拉相关状态
const isSearchFocused = ref(false);
const showDropdown = ref(false);
const isSearching = ref(false);
const searchInputRef = ref(null);
const hasMore = ref(true); // 是否还有更多数据
const isLoadingMore = ref(false); // 是否正在加载更多
const selectedVulnerability = ref(null);
const rec = reactive({
  vulnList: [],
  list: [],
  title: "",
  checkedId: 0,
  bigDataAnalysis: {},
  isMatching: false,
  matchingProgress: 0,
});
// 查看详情
const detailVisible = ref(false);
const currentVulnData = ref({});
const handleViewDetails = (row) => {
  getVulnDetailFn(row.vuln_id)
};
// 获取漏洞详情数据
const getVulnDetailFn = async (vuln_id) => {
  try {
    const res = await getVulnDetailById({vuln_id: vuln_id});
    if (res.code === 200) {
      currentVulnData.value = res?.data || {}
      detailVisible.value = true;
    }
  } catch (error) {
    currentVulnData.value = {}
  }
}
// 详情弹窗关闭
const handleDetailClosed = () => {
  currentVulnData.value = {};
};
// 搜索焦点处理
const handleSearchFocus = () => {
  isSearchFocused.value = true;
  showDropdown.value = true;
  // 如果没有数据且没有搜索词，则加载初始数据
  if (rec.list.length === 0 && !rec.title) {
    fetchInputData();
  }
};

const handleSearchBlur = () => {
  // 延迟隐藏下拉框，允许点击事件完成
  setTimeout(() => {
    isSearchFocused.value = false;
    showDropdown.value = false;
  }, 200);
};

const handleSearchClear = () => {
  rec.title = "";
  rec.list = [];
  page.value = 1;
  hasMore.value = true;
  showDropdown.value = false;
};

// 处理搜索输入 - 添加防抖
const searchDebounceTimer = ref(null)
const handleSearchInput = () => {
  if (searchDebounceTimer.value) {
    clearTimeout(searchDebounceTimer.value);
  }

  searchDebounceTimer.value = setTimeout(() => {
    showDropdown.value = true;
    fetchInputData();
  }, 300); // 300ms 防抖
};

// 下拉框滚动事件
const handleDropdownScroll = (e) => {
  const target = e.target;
  const { scrollTop, scrollHeight, clientHeight } = target;
  // 当滚动到距离底部20px时触发加载
  if (
    scrollHeight - scrollTop - clientHeight < 20 &&
    !isLoadingMore.value &&
    hasMore.value
  ) {
    loadMore();
  }
};

// 加载更多数据
const loadMore = debounce(async () => {
  if (isLoadingMore.value || !hasMore.value) return;

  isLoadingMore.value = true;
  page.value++;

  try {
    const params = {
      page_index: page.value,
      page_size: limit.value,
      title: rec.title,
    };

    const res = await getVulnerabilityList(params);
    const newList = res.data || [];

    if (newList.length < limit.value) {
      hasMore.value = false;
    }

    rec.list = [...rec.list, ...newList];
  } catch (error) {
    isLoadingMore.value = false;
    page.value--; // 加载失败时回退页码
  } finally {
    isLoadingMore.value = false;
  }
}, 300);

// 获取列表数据
const fetchInputData = async () => {
  try {
    isSearching.value = true;
    page.value = 1; // 重置页码
    hasMore.value = true; // 重置加载状态

    const params = {
      page_index: page.value,
      page_size: limit.value,
      title: rec.title,
    };

    const res = await getVulnerabilityList(params);
    rec.list = res.data || [];

    // 判断是否还有更多数据
    if (rec.list.length < limit.value) {
      hasMore.value = false;
    }
  } catch (error) {
    console.error("获取漏洞列表失败:", error);
    ElMessage.error("获取漏洞列表失败");
  } finally {
    isSearching.value = false;
  }
};
// 高亮搜索匹配文本
const highlightMatch = (text, searchText) => {
  if (!searchText || !text) return text;

  const regex = new RegExp(
    `(${searchText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`,
    "gi"
  );
  return text.replace(regex, '<mark class="search-highlight">$1</mark>');
};
// 获取标签类型
const getTagType = (level) => {
  const typeMap = {
    严重: "danger",
    高: "warning",
    中: "",
    低: "info",
  };
  return typeMap[level] || "";
};
// 格式化危害等级
const formatLevel = (level) => {
  const levelMap = {
    critical: "严重",
    high: "高危",
    medium: "中危",
    low: "低危",
  };
  return levelMap[level] || level;
};
// 选择漏洞
const selectVulnerability = (vuln) => {
  // 先设置选择状态
  rec.checkedId = vuln.id;
  selectedVulnerability.value = vuln;
  showDropdown.value = false;

  ElMessageBox.confirm("是否确认创建分析任务？", "确认", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      const data = {
        vuln_id: vuln.id,
      };
      const res = await createVulnTask(data);
      if (res.code === 200) {
        ElMessage.success("任务创建成功");
        rec.title = "";
        fetchData();
        // 可以在这里添加其他成功后的逻辑
      } else {
        ElMessage.error(res.msg || "任务创建失败");
      }
    })
    .catch(() => {
      ElMessage.info("已取消创建任务");
      // 如果取消，可以选择是否清除选择
      // clearSelection()
    });
};

// 根据状态获取样式类名
const getStatusClass = (status) => {
  if (status > 100) {
    return "status-failed";
  } else {
    return "status-running";
  }
};

onMounted(() => {
  fetchData();
  timerId.value = setInterval(fetchData, 10000);
});

onUnmounted(() => {
  if (timerId.value) {
    clearInterval(timerId.value);
    timerId.value = null;
  }
});
// 删除
const handleDelete = async (source) => {
  ElMessageBox.confirm(`确定要删除 ${source.title} 的数据源吗？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const response = await deleteVulnTask({ id: source.id });
    ElMessage.success(response.msg);
    fetchData();
  });
};
const fetchData = async () => {
  loading.value = true;
  try {
    let params;
    if (dateRange.value && dateRange.value.length) {
      params = {
        page_index: page.value,
        page_size: limit.value,
        // name: name.value,
        start_time: dateRange.value[0]
          ? dayjs(dateRange.value[0]).format("YYYY-MM-DD")
          : "",
        end_time: dateRange.value[1]
          ? dayjs(dateRange.value[1]).format("YYYY-MM-DD")
          : "",
        title: vuln_title.value,
      };
    } else {
      params = {
        page_index: page.value,
        page_size: limit.value,
        // name: name.value,
        title: vuln_title.value,
      };
    }
    const res = await getTaskList(params);
    if (res.code === 200) {
      total.value = res.total_items;
      tableData.value = res.data;
    }
  } catch (error) {
    console.error("获取验证记录失败", error);
    ElMessage.error("获取验证记录列表失败");
  } finally {
    loading.value = false;
  }
};

// 详情
const handleDetail = async (row) => {
  console.log("row", row);
  detailInfo.value = row;
  visible.value = true;
};

// 处理日期范围变化
const handleDateRangeChange = (val) => {
  dateRange.value = val;
};

// 处理搜索
const handleSearch = () => {
  page.value = 1;
  fetchData();
};

// 处理重置
const handleReset = () => {
  dateRange.value = [];
  vuln_title.value = "";
  // name.value = '';
  // Object.keys(searchForm).forEach((key) => {
  //   searchForm[key] = "";
  // });
  handleSearch();
};
// 处理分页
const handlePagination = () => {
  fetchData();
};

// 处理选择行变化
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
</script>

<style lang="scss" scoped>
.verification-record-list {
  padding: 16px;

  .header-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    h1 {
      font-size: 20px;
      font-weight: bold;
      margin: 0;
    }
  }

  // 状态徽章样式
  .status-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    font-size: 13px;
    min-width: 90px;
    font-weight: 500;

    .status-indicator {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      margin-right: 6px;
      display: inline-block;
    }

    &.status-success {
      background-color: rgba(19, 206, 102, 0.15);
      color: #13ce66;

      .status-indicator {
        background-color: #13ce66;
        box-shadow: 0 0 0 2px rgba(19, 206, 102, 0.2);
      }
    }

    &.status-failed {
      background-color: rgba(245, 108, 108, 0.15);
      color: #f56c6c;

      .status-indicator {
        background-color: #f56c6c;
        box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.2);
      }
    }

    &.status-running {
      background-color: rgba(24, 144, 255, 0.15);
      color: #1890ff;

      .status-indicator {
        background-color: #1890ff;
        box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
      }
    }

    &.status-waiting {
      background-color: rgba(230, 162, 60, 0.15);
      color: #e6a23c;

      .status-indicator {
        background-color: #e6a23c;
        box-shadow: 0 0 0 2px rgba(230, 162, 60, 0.2);
      }
    }

    &.status-default {
      background-color: rgba(144, 147, 153, 0.15);
      color: #909399;

      .status-indicator {
        background-color: #909399;
        box-shadow: 0 0 0 2px rgba(144, 147, 153, 0.2);
      }
    }
  }

  :deep(.el-table) {
    --el-table-border-color: var(--el-border-color-lighter);
    --el-table-header-bg-color: var(--el-fill-color-light);
  }

  :deep(.el-pagination) {
    margin-top: 20px;
    justify-content: flex-end;
  }
}

// 暗色主题适配
html.dark {
  .verification-record-list {
    .status-badge {
      &.status-success {
        background-color: rgba(19, 206, 102, 0.15);
        color: #13ce66;
      }

      &.status-failed {
        background-color: rgba(245, 108, 108, 0.15);
        color: #f56c6c;
      }

      &.status-running {
        background-color: rgba(24, 144, 255, 0.15);
        color: #1890ff;
      }

      &.status-waiting {
        background-color: rgba(230, 162, 60, 0.15);
        color: #e6a23c;
      }

      &.status-default {
        background-color: rgba(144, 147, 153, 0.15);
        color: #909399;
      }
    }
  }
}
// 搜索下拉组件样式
.search-dropdown-container {
  position: relative;
  // margin-bottom: 20px;
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  font-size: 14px;
  gap: 10px;

  .search-input-wrapper {
    position: relative;
    width: 500px;    

    &.is-focus {
      .search-icon {
        color: var(--el-color-primary);
      }
    }

    .search-icon {
      transition: all 0.3s ease;

      &.rotate {
        animation: rotate 1s linear infinite;
      }
    }

    .search-dropdown {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      z-index: 9999; // 提高层级，防止被遮挡
      background: var(--el-bg-color);
      border: 1px solid var(--el-border-color);
      border-radius: 6px;
      box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
      max-height: 400px;
      overflow: hidden;
      margin-top: 4px;

      .dropdown-content {
        max-height: 400px;
        overflow-y: auto;

        &::-webkit-scrollbar {
          width: 6px;
        }

        &::-webkit-scrollbar-thumb {
          background-color: var(--el-border-color);
          border-radius: 3px;

          &:hover {
            background-color: var(--el-border-color-darker);
          }
        }

        &::-webkit-scrollbar-track {
          background-color: var(--el-fill-color-light);
        }
      }

      .dropdown-item {
        padding: 12px 16px;
        border-bottom: 1px solid var(--el-border-color-lighter);
        cursor: pointer;
        transition: all 0.2s ease;

        &:last-child {
          border-bottom: none;
        }

        &:hover {
          background-color: var(--el-fill-color-light);
        }

        &.is-selected {
          background-color: var(--el-color-primary-light-9);
          border-left: 3px solid var(--el-color-primary);
        }

        .item-content {
          .item-title {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 6px;
            font-weight: 500;
            .text {
              width: 80%;
            }
            span {
              margin-right: 8px;
              word-break: break-all;
            }
          }

          .item-meta {
            display: flex;
            gap: 12px;
            font-size: 12px;
            color: var(--el-text-color-secondary);

            .item-id,
            .item-type {
              flex-shrink: 0;
            }
          }
        }
      }

      .loading-more-item,
      .no-more-item,
      .no-result-item {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        padding: 16px;
        color: var(--el-text-color-secondary);
        font-size: 14px;

        .el-icon {
          font-size: 16px;
        }
      }

      .no-result-item {
        color: var(--el-text-color-placeholder);
      }
    }
  }

  // 已选择的漏洞显示
  .selected-vuln-display {
    margin-top: 12px;
    padding: 12px;
    background-color: var(--el-fill-color-light);
    border-radius: 6px;
    border: 1px solid var(--el-border-color-lighter);

    .selected-label {
      font-size: 12px;
      color: var(--el-text-color-secondary);
      margin-bottom: 6px;
    }

    .selected-content {
      display: flex;
      align-items: center;
      gap: 8px;

      .selected-title {
        flex: 1;
        font-weight: 500;
        word-break: break-all;
      }
    }
  }
}

.top {
  width: 100%;
  :deep(.el-card) {
    overflow: revert;
  }
}
.overflow-visible {
  :deep(.el-card) {
    overflow: visible;
  }
}
</style>
